package com.bxj.mybatis.generator.plugin;

import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.config.PropertyRegistry;
import org.mybatis.generator.internal.NullProgressCallback;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

public class ApiPlugin extends PluginAdapter {


    private String javaProject;
    private String javaPackage;
    private String rootClass;
    private String interfacePackage;
    private String dto = "";

    public boolean validate(List<String> warnings) {
        javaProject = properties.getProperty("javaProject");
        if (StringUtils.isEmpty(javaProject))
            return false;
        javaPackage = properties.getProperty("javaPackage");
        if (StringUtils.isEmpty(javaPackage))
            return false;
        interfacePackage = properties.getProperty("interfacePackage");
        if (StringUtils.isEmpty(interfacePackage))
            return false;
        rootClass = properties.getProperty("rootClass");

        String contextEnableDto = context.getProperty("enableDto");
        String enableDto = properties.getProperty("enableDto");
        if ("true".equals(enableDto) || "true".equals(contextEnableDto))
            dto = "Dto";

        return true;
    }

    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {

        List<GeneratedJavaFile> answer = new ArrayList<GeneratedJavaFile>();
        SimpleModelGenerator javaGenerator = new SimpleModelGenerator();
        javaGenerator.setContext(context);
        javaGenerator.setProgressCallback(new NullProgressCallback());
        javaGenerator.setIntrospectedTable(introspectedTable);
        String shortName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();
        String dtoName = javaPackage + "." + shortName + dto;
        if (!MybatisUtils.checkReplaceIfExists(introspectedTable, javaProject, javaPackage, shortName + dto + ".java"))
            return answer;
        javaGenerator.setTopLevelClass(new TopLevelClass(new FullyQualifiedJavaType(dtoName)));
//        introspectedTable.setBaseRecordType(dtoName);
        javaGenerator.setRootClass(rootClass);
        List<CompilationUnit> compilationUnits = javaGenerator
                .getCompilationUnits();
        for (CompilationUnit compilationUnit : compilationUnits) {

//            ublic String getFileName() {
//                return compilationUnit.getType().getShortNameWithoutTypeArguments() + ".java"; //$NON-NLS-1$
//            }
            GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,
                    javaProject,
                    context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
                    context.getJavaFormatter());
            answer.add(gjf);
        }

        String serviceName = "I" + shortName + "DubboService";
        if (!MybatisUtils.checkReplaceIfExists(introspectedTable, javaProject, interfacePackage, serviceName + ".java"))
            return answer;
        Interface serviceInterface = new Interface(interfacePackage + "." + serviceName);
        serviceInterface.setVisibility(JavaVisibility.PUBLIC);
        MybatisUtils.addJavaDocLines(serviceInterface);
        answer.add(addSelectSelectiveMethod(serviceInterface, introspectedTable));
        answer.add(addSelectObjectByIdMethod(serviceInterface, introspectedTable));
        answer.add(addSelectPageMethod(serviceInterface, introspectedTable));
        answer.add(addInsertMethod(serviceInterface, introspectedTable));
//        answer.add(addDeleteByPrimaryKeyMethod(serviceInterface, introspectedTable));
        answer.add(addUpdateByPrimaryKeySelectiveMethod(serviceInterface, introspectedTable));

        return answer;
    }

    private GeneratedJavaFile addSelectObjectByIdMethod(Interface serviceInterface, IntrospectedTable introspectedTable) {
        Method method = new Method();
        String shortName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();
        String paramName = shortName.substring(0, 1).toLowerCase() + shortName.substring(1);
        method.setName(MybatisUtils.getTableProperties(introspectedTable, "selectByPrimaryKeyStatementId", "selectById"));
        if (introspectedTable.getPrimaryKeyColumns().size() > 0)
            method.addParameter(new Parameter(introspectedTable.getPrimaryKeyColumns().get(0).getFullyQualifiedJavaType(), "id", false));
        serviceInterface.addImportedType(new FullyQualifiedJavaType(javaPackage + "." + shortName + dto));
        serviceInterface.addImportedType(new FullyQualifiedJavaType("java.util.List"));
        method.setReturnType(new FullyQualifiedJavaType(shortName + dto));
        serviceInterface.addMethod(method);

        return new GeneratedJavaFile(serviceInterface, javaProject, context.getJavaFormatter());
    }

    private GeneratedJavaFile addSelectSelectiveMethod(Interface serviceInterface, IntrospectedTable introspectedTable) {
        Method method = new Method();
        String shortName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();
        String paramName = shortName.substring(0, 1).toLowerCase() + shortName.substring(1);
        method.setName(MybatisUtils.getTableProperties(introspectedTable, "selectSelectiveStatementId", "selectSelective"));

        method.addParameter(new Parameter(new FullyQualifiedJavaType(shortName + dto), paramName + dto, false));
        serviceInterface.addImportedType(new FullyQualifiedJavaType(javaPackage + "." + shortName + dto));
        serviceInterface.addImportedType(new FullyQualifiedJavaType("java.util.List"));
        method.setReturnType(new FullyQualifiedJavaType("List<" + shortName + dto + ">"));
        serviceInterface.addMethod(method);

        return new GeneratedJavaFile(serviceInterface, javaProject, context.getJavaFormatter());
    }

    private GeneratedJavaFile addSelectPageMethod(Interface serviceInterface, IntrospectedTable introspectedTable) {
        String shortName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();
        String paramName = shortName.substring(0, 1).toLowerCase() + shortName.substring(1);
        Method method = new Method();
        method.setName(MybatisUtils.getTableProperties(introspectedTable, "selectPageStatementId", "selectPage"));
        method.addParameter(new Parameter(new FullyQualifiedJavaType(shortName + dto), paramName + dto, false));
        serviceInterface.addImportedType(new FullyQualifiedJavaType(javaPackage + "." + shortName + dto));
        serviceInterface.addImportedType(new FullyQualifiedJavaType("com.ifeng.matrix.common." + (dto.isEmpty() ? "domain.PageResult" : "dto.PageResultDto")));
        method.setReturnType(new FullyQualifiedJavaType("PageResult" + dto + "<" + shortName + dto + ">"));
        serviceInterface.addMethod(method);

        GeneratedJavaFile mapperJavafile = new GeneratedJavaFile(serviceInterface, javaProject, context.getJavaFormatter());
        return mapperJavafile;
    }

    private GeneratedJavaFile addInsertMethod(Interface serviceInterface, IntrospectedTable introspectedTable) {
        String shortName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();
        String paramName = shortName.substring(0, 1).toLowerCase() + shortName.substring(1);
        Method method = new Method();
        method.setName(MybatisUtils.getTableProperties(introspectedTable, "insertStatementId", "insert"));
        method.addParameter(new Parameter(new FullyQualifiedJavaType(shortName + dto), paramName + dto, false));
        serviceInterface.addImportedType(new FullyQualifiedJavaType(javaPackage + "." + shortName + dto));
        method.setReturnType(FullyQualifiedJavaType.getIntInstance());
        serviceInterface.addMethod(method);

        GeneratedJavaFile mapperJavafile = new GeneratedJavaFile(serviceInterface, javaProject, context.getJavaFormatter());
        return mapperJavafile;
    }

    private GeneratedJavaFile addDeleteByPrimaryKeyMethod(Interface serviceInterface, IntrospectedTable introspectedTable) {
        String shortName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();
        String paramName = shortName.substring(0, 1).toLowerCase() + shortName.substring(1);
        Method method = new Method();
        method.setName(MybatisUtils.getTableProperties(introspectedTable, "deleteByPrimaryKeyStatementId", "deleteById"));
        if (introspectedTable.getPrimaryKeyColumns().size() > 0)
            method.addParameter(new Parameter(introspectedTable.getPrimaryKeyColumns().get(0).getFullyQualifiedJavaType(), "id", false));
        serviceInterface.addImportedType(new FullyQualifiedJavaType(javaPackage + "." + shortName + dto));
        method.setReturnType(FullyQualifiedJavaType.getIntInstance());
        serviceInterface.addMethod(method);

        GeneratedJavaFile mapperJavafile = new GeneratedJavaFile(serviceInterface, javaProject, context.getJavaFormatter());
        return mapperJavafile;
    }

    private GeneratedJavaFile addUpdateByPrimaryKeySelectiveMethod(Interface serviceInterface, IntrospectedTable introspectedTable) {
        String shortName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();
        String paramName = shortName.substring(0, 1).toLowerCase() + shortName.substring(1);
        Method method = new Method();
        method.setName(MybatisUtils.getTableProperties(introspectedTable, "updateByPrimaryKeySelectiveStatementId", "updateSelectiveById"));
        method.addParameter(new Parameter(new FullyQualifiedJavaType(shortName + dto), paramName + dto, false));
        serviceInterface.addImportedType(new FullyQualifiedJavaType(javaPackage + "." + shortName + dto));
        method.setReturnType(FullyQualifiedJavaType.getIntInstance());
        serviceInterface.addMethod(method);

        GeneratedJavaFile mapperJavafile = new GeneratedJavaFile(serviceInterface, javaProject, context.getJavaFormatter());
        return mapperJavafile;
    }


}
